\documentclass{ctexart}
\usepackage{listings}%插入代码
\usepackage{geometry}%设置页面大小边距等
\usepackage{graphicx}%插入图片
\usepackage{amssymb}%为了用\mathbb
\usepackage{amsmath}%数学方程的显示
\usepackage{listings}%插入代码
\usepackage{fancyhdr}%设置页眉页脚
\usepackage{lastpage}%总页数
\usepackage{hyperref}%引用网页
\usepackage{xcolor}
\usepackage{tikz}
\usepackage{float}


\geometry{a4paper,left=2cm,right=2cm,top=2cm,bottom=2cm}%一定要放在前面！
\pagestyle{fancy}%设置页眉页脚
\lhead{陈冠宇\ 3200102033}%页眉左
\chead{Numerical Methods for Differential Equations}%页眉中
\rhead{Project3}%章节信息
\cfoot{\thepage/\pageref{LastPage}}%当前页，记得调用前文提到的宏包
\lfoot{Zhejiang University}
\rfoot{School of Mathematical Sciences}
\renewcommand{\headrulewidth}{0.1mm}%页眉线宽，设为0可以去页眉线
\renewcommand{\footrulewidth}{0.1mm}%页脚线宽，设为0可以去页眉线
\setlength{\headwidth}{\textwidth}

\hypersetup{%设置网页链接颜色等
    colorlinks=true,%链接将会有颜色，默认是红色
    linkcolor=blue,%内部链接，那些由交叉引用生成的链接将会变为蓝色（blue）
    filecolor=magenta,%链接到本地文件的链接将会变为洋红色（magenta）
    urlcolor=blue,%链接到网站的链接将会变为蓝绿色（cyan）
    }

\lstset{
	columns=fixed,       
	% numbers=left,
	% numberstyle=\tiny\color{gray},
	frame=lrtb,
	basicstyle=\ttfamily, 
	backgroundcolor=\color[RGB]{245,245,244},
	keywordstyle=\color[RGB]{40,40,255},
	numberstyle=\footnotesize\color{darkgray},           
	commentstyle=\it\color[RGB]{0,96,96},
	stringstyle=\rmfamily\slshape\color[RGB]{128,0,0},
	showstringspaces=false,
	language=c++,
}
\newtheorem{theorem}{Theorem}
\newtheorem{proof}{Proof}
\newtheorem{solution}{Solution:}

\title{\textbf{微分方程数值解第三次大作业}}
\date{\today}

\begin{document}
\section*{Project3}
\subsection*{运行说明}
input.json和input1.json 文件分别输入了$T_1,T_2$两种初始值。输出结果将数据输入到output.m文件中，利用matlab画图，在终端命令行输出误差值，并用time ./a.out计时。

在project3文件夹下,命令行输入make run将编译main.cpp和test.cpp，输入make story将编译report.tex报告。
\subsection*{1.Base Class: TimeIntegrator}
    TimeIntegrator作为抽象基类，内容非常简略，只有一个求解器的抽象函数,构造函数以及误差求解器。
\begin{lstlisting}
class TimeIntegrator
{
public:
    TimeIntegrator(){}
    virtual void solver(){}
    virtual void error(){}
};
\end{lstlisting}
设计了对象工厂
\begin{lstlisting}
class TimeIntergratorFactory
{
public:
    using CreateMethodCallback = TimeIntegrator *(*)(int n_, int p_, double T_, vector<double> value_);

private:
    using CallbackMap = map<string, CreateMethodCallback>;
    CallbackMap callbacks_;
    TimeIntergratorFactory() = default;
    TimeIntergratorFactory(const TimeIntergratorFactory &) = default;
    TimeIntergratorFactory &operator=(const TimeIntergratorFactory &) = default;
    ~TimeIntergratorFactory() = default;

public:
    static TimeIntergratorFactory &createFactory()
    {
        static TimeIntergratorFactory object;
        return object;
    }
    void registerProduct(const string &Id, TimeIntegrator *(*createFn)(int n_, int p_, double T_, vector<double> value_))
    {
        callbacks_[Id] = createFn;
    }

    TimeIntegrator *create(const string &ID, const int &n_, const int &p_, const double &T_, const vector<double> &value_)
    {
        auto it = callbacks_.find(ID);
        if (it != callbacks_.end())
        {
            return it->second(n_, p_, T_, value_);
        }
        return nullptr;
    }
};
\end{lstlisting}

在main.cpp中可以通过修改
\begin{lstlisting}
auto obj = TimeIntergratorFactory::createFactory().create("AdamsBashforth", n_steps, p, T, value);
\end{lstlisting}
中的AdamsBashforth字段进行注册不同的对象，同时我们可以通过修改输入的文件名称input1.json还是input.json(分别是两种周期)

test.cpp里面是没有用对象工厂实现的程序，是一开始写的。
\subsection*{2.Tests}
\subsubsection*{2.1 AdamsBashforth}
\begin{center}
    \begin{tabular}{|c|c|c|c|c|}
        \hline
         & \multicolumn{2}{c|}{(10.198) with $T_1$ and $p=4$} & \multicolumn{2}{c|}{(10.199) with $T_2$ and $p=4$} \\
         \hline
         steps & solution error & CPU time (s) & solution error & CPU time (s) \\
         \hline
         24000 & 0.131055 & 0.258 & 1.96722e-08 & 0.234 \\
         \hline
         48000 & 0.018803 & 0.479 & 9.51355e-10 & 0.476 \\
         \hline
         96000 & 0.00174041 & 0.904 & 5.79908e-11 & 0.928 \\
         \hline
    \end{tabular}
\end{center}
我们可以看到随着步数的增加，其误差基本上是原来的$\frac{1}{16}$,即基本是 4 阶收敛的，符合预期。
对于 (10.199)，随着步数增加一倍，误差基本上缩小为原来$\frac{1}{8}$,即基本是 3 阶收敛的，符合预期。
\subsubsection*{2.2 AdamsMoulton}
\begin{center}
    \begin{tabular}{|c|c|c|c|c|}
        \hline
         & \multicolumn{2}{c|}{(10.198) with $T_1$ and $p=3$} & \multicolumn{2}{c|}{(10.199) with $T_2$ and $p=3$} \\
         \hline
         steps & solution error & CPU time (s) & solution error & CPU time (s) \\
         \hline
         24000 & 0.0711082 & 0.274 & 2.50412e-05 & 0.420\\
         \hline
         48000 & 0.0124587 & 0.555 & 3.13067e-06 & 0.705 \\
         \hline
         96000 & 0.00232905 & 1.045 & 3.91354e-07 & 1.694 \\
         \hline
    \end{tabular}
\end{center}
\par 可以看到，对于(10.198)，随着步数的增加一倍，其误差基本上是缩小为原来的$\frac{1}{8}$，即基本是3阶收敛的，符合预期。对于(10.199)，随着步数增加一倍，误差基本上缩小为原来的$\frac{1}{8}$，即基本是3阶收敛的，符合预期。

\subsubsection*{2.3 Back Differentiation Formulas}
\begin{center}
    \begin{tabular}{|c|c|c|c|c|}
        \hline
         & \multicolumn{2}{c|}{(10.198) with $T_1$ and $p=4$} & \multicolumn{2}{c|}{(10.199) with $T_2$ and $p=4$} \\
         \hline
         steps & solution error & CPU time (s) & solution error & CPU time (s) \\
         \hline
         24000 & 0.0140197 & 0.317 & 2.63175e-08 & 0.320 \\
         \hline
         48000 & 0.0073359 & 0.588 & 9.15151e-10 & 0.602 \\
         \hline
         96000 & 0.000876119 & 1.176 & 4.68955e-11 & 1.173\\
         \hline
    \end{tabular}
    \end{center}
\subsubsection*{2.4 Classical Runge-Kutta}
\begin{center}
    \begin{tabular}{|c|c|c|c|c|}
        \hline
         & \multicolumn{2}{c|}{(10.198) with $T_1$} & \multicolumn{2}{c|}{(10.199) with $T_2$} \\
         \hline
         steps & solution error & CPU time (s) & solution error & CPU time (s) \\
         \hline
         24000 & 0.00115963 & 0.274 & 9.03183e-11 & 0.270 \\
         \hline
         48000 & 6.55e-05 & 0.482 & 1.05136e-11 & 0.508 \\
         \hline
         96000 & 3.85817e-06 & 0.983 & 1.65311e-11 & 0.973\\
         \hline
    \end{tabular}
\end{center}
\subsubsection*{2.5 ESDIRK}
\begin{center}
    \begin{tabular}{|c|c|c|c|c|}
        \hline
         & \multicolumn{2}{c|}{(10.198) with $T_1$} & \multicolumn{2}{c|}{(10.199) with $T_2$} \\
         \hline
         steps & solution error & CPU time (s) & solution error & CPU time (s) \\
         \hline
         24000 & 0.000352641 & 1.194 & 4.77004e-10 & 1.330 \\
         \hline
         48000 & 2.20851e-05 & 2.298 & 1.29648e-09 & 2.405 \\
         \hline
         96000 & 1.39155e-06 & 4.481  & 6.57769e-10 & 4.843\\
         \hline
    \end{tabular}
\end{center}
\subsubsection*{2.6 Gauss-Legendre RK}
\begin{center}
    \begin{tabular}{|c|c|c|c|c|}
        \hline
         & \multicolumn{2}{c|}{(10.198) with $T_1$ and $s=2$} & \multicolumn{2}{c|}{(10.199) with $T_2$ and $s=1$} \\
         \hline
         steps & solution error & CPU time (s) & solution error & CPU time (s) \\
         \hline
         24000 & 0.000229239 & 0.571 & 5.14309e-05 & 0.312\\
         \hline
         48000 & 1.46214e-05& 1.133 & 1.28584e-05& 0.580\\
         \hline
         96000 & 9.1817e-07 & 2.062 & 3.21197e-06 & 1.102 \\
         \hline
    \end{tabular}
    \end{center}
\subsubsection*{2.7 Fehlberg 4(5) embedded RK}
\begin{center}
    \begin{tabular}{|c|c|c|c|c|}
        \hline
         & \multicolumn{2}{c|}{(10.198) with $T_1$} & \multicolumn{2}{c|}{(10.199) with $T_2$} \\
         \hline
         step size & solution error & CPU time (s) & solution error & CPU time (s) \\
         \hline
         0.1 & 0.000413538 & 0.016 & 0.000475863 & 0.022\\
         \hline
    \end{tabular}
\end{center}
\subsubsection*{2.8 Dormand-Prince 5(4) embedded RK}
\begin{center}
    \begin{tabular}{|c|c|c|c|c|}
        \hline
         & \multicolumn{2}{c|}{(10.198) with $T_1$} & \multicolumn{2}{c|}{(10.199) with $T_2$} \\
         \hline
         step size & solution error & CPU time (s) & solution error & CPU time (s) \\
         \hline
         0.1 & 0.0115292 & 0.068 & 0.0275391 & 0.064 \\
         \hline
    \end{tabular}
\end{center}
\subsection*{3. Plot}
\subsubsection*{3.1 Euler Method}
24000步的Euler方法:
\begin{figure}[H]
    \centering
    %\subfigure
    %{
        \begin{minipage}{0.48\textwidth}
        \centering
        \caption{(10.198) with $T_1$}
        \includegraphics[scale=0.48]{./pic/E1.png}
        \end{minipage}
    %}
    %\subfigure
    %{
        \begin{minipage}{0.48\textwidth}
        \centering
        \caption{(10.199) with $T_2$}
        \includegraphics[scale=0.48]{./pic/E2.png}
        \end{minipage}
    %}
    \label{fig:2}
\end{figure}
\subsubsection*{3.2 Classical RK}
24000步的Classical 方法:
\begin{figure}[H]
    \centering
    %\subfigure
    %{
        \begin{minipage}{0.48\textwidth}
        \centering
        \caption{(10.198) with $T_1$}
        \includegraphics[scale=0.48]{./pic/C1.png}
        \end{minipage}
    %}
    %\subfigure
    %{
        \begin{minipage}{0.48\textwidth}
        \centering
        \caption{(10.199) with $T_2$}
        \includegraphics[scale=0.48]{./pic/C2.png}
        \end{minipage}
    %}
    \label{fig:2}
\end{figure}
\subsubsection*{3.3 Dormand-Prince Method}
initial step size = 0.1
\begin{figure}[H]
    \centering
    %\subfigure
    %{
        \begin{minipage}{0.48\textwidth}
        \centering
        \caption{(10.198) with $T_1$}
        \includegraphics[scale=0.48]{./pic/D1.png}
        \end{minipage}
    %}
    %\subfigure
    %{
        \begin{minipage}{0.48\textwidth}
        \centering
        \caption{(10.199) with $T_2$}
        \includegraphics[scale=0.48]{./pic/D2.png}
        \end{minipage}
    %}
    \label{fig:2}
\end{figure}
\end{document} 
